package com.zmn.oms.third.base.util;


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.utils.date.DateUtil;

import java.text.SimpleDateFormat;
import java.util.*;

import static com.zmn.common.utils.date.DateUtil.UNIT_MINUTE;

/**
 * 天猫端预约时间规则
 * 1.预约时间的开始时间点。和结束时间点
 *   目前只允许填 8:00-10:00，10:00-12:00，12:00-14:00，14:00-16:00，16:00-18:00，18:00-20:00、20:00-21:00
 * 2.需判断 预约时间 当前时间 指定时间点
 *   1.当前时小于某一个预约时间段的开始时间 && 预约时间在该时间段内，设置该预约时间段 eg.当前时间小于10点，预约时间在10:00-12:00，则设置为10:00-12:00
 *   2.当前时间 && 预约时间 都在某一个预约时间段内，设置预约时间为下一个预约时间段 eg.都在8:00-10:00 则设置为10:00-12:00
 *   3.预约时间在当日零点 && 次日上午8点以前 返回次日最早时间段
 *   4.预约时间在00：00：00 以后 && 08：00以前 返回当日最早时间段
 */
public class DutyTimeUtil {
    /**
     * 预约时间获取预约时间段 eg, 2019-10-23 16:00:00,2019-10-23 18:00:00
     *
     * @param dutyTime
     * @return
     */
    public static String getDutyTime(String dutyTime) {
        Map<Object, String> map = dutyTimeBase(dutyTime);
        for (Map.Entry<Object, String> entry : map.entrySet()) {
            List duty = getDutyList(entry.getValue());
            //预约时间在指定时间内
            boolean dutyTimeCompare = belongCalendar(DateUtil.parse(dutyTime), DateUtil.parse(duty.get(0).toString()), DateUtil.parse(duty.get(1).toString()));
            //当前时间不在指定开始时间内
            boolean getResultBeginTimeCompareToNow = compare(DateUtil.getNowFormatted(), duty.get(0).toString());

            if (dutyTimeCompare && getResultBeginTimeCompareToNow) {
                return entry.getValue();
            } else if (dutyTimeCompare) {
                return map.get((Integer) entry.getKey() + 1);
            }

        }
        //预约时间在零点以后八点以前返回最早时间
        boolean getResultDutyTimeCompareToStart = compare(DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 00:00:00"), dutyTime);
        boolean getResultDutyTimeCompareToEnd = compare(dutyTime, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 08:00:00"));
        if (getResultDutyTimeCompareToStart && getResultDutyTimeCompareToEnd) {
            //预约时间在00：00：00 以后 08：00以前
            return map.get(1);
        }

        return map.get(8);
    }

    /**
     * 初始化预约时间段规则
     *
     * @param dutyTime
     * @return
     */
    public static Map<Object, String> dutyTimeBase(String dutyTime) {
        Map<Object, String> dutyTimeMap = Maps.newHashMap();
        dutyTimeMap.put(1, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 08:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 10:00:00"));
        dutyTimeMap.put(2, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 10:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 12:00:00"));
        dutyTimeMap.put(3, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 12:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 14:00:00"));
        dutyTimeMap.put(4, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 14:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 16:00:00"));
        dutyTimeMap.put(5, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 16:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 18:00:00"));
        dutyTimeMap.put(6, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 18:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 20:00:00"));
        dutyTimeMap.put(7, DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 20:00:00") + "," + DateUtil.toString(DateUtil.parse(dutyTime), "yyyy-MM-dd 21:00:00"));
        dutyTimeMap.put(8, getDayAfter(dutyTime) + " 08:00:00" + "," + getDayAfter(dutyTime) + " 10:00:00");
        return dutyTimeMap;
    }

    /**
     * 分割字符串
     *
     * @param dutyTimeString
     * @return
     */
    public static List getDutyList(String dutyTimeString) {
        String[] dutyTime = dutyTimeString.split(",");
        return Lists.newArrayList(dutyTime);
    }

    /**
     * * 判断时间是否在时间段内
     * * @param nowTime
     * * @param beginTime（包含）
     * * @param endTime
     * * @return
     *      
     */
    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {

        if (nowTime.getTime() == beginTime.getTime()) {
            return true;
        }
        //设置当前时间
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        //设置开始时间
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        //设置结束时间
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        //处于开始时间之后，和结束时间之前的判断
        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 时间+1天
     *
     * @param dutyTime
     * @return
     */
    public static String getDayAfter(String dutyTime) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtil.parse(dutyTime));
        c.add(Calendar.DAY_OF_MONTH, 1);
        return sf.format(c.getTime());
    }

    /**
     * 时间比较
     *
     * @param time
     * @param compareTime
     * @return
     */
    public static boolean compare(String time, String compareTime) {
        Date a = DateUtil.parse(time);
        Date b = DateUtil.parse(compareTime);
        if (a.before(b)) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * 时间按分钟取整点或向上取半点
     *  例如：传入2018-10-01 10:10:00，返回2018-10-01 10:30:00
     * @param date
     * @return
     */
    public static Date round(Date date, int unitType) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (UNIT_MINUTE == unitType) {
            int minute = calendar.get(Calendar.MINUTE);
            if ((0 <= minute) && (minute < 30)) {
                calendar.set(Calendar.MINUTE, 30);
                calendar.set(Calendar.SECOND, 0);
            }
            else {
                calendar.set(Calendar.MINUTE, 0);
                if (30 <= minute) {
                    calendar.add(Calendar.HOUR, 1);
                    calendar.set(Calendar.SECOND, 0);
                }
            }
        }
        return calendar.getTime();
    }

    public static void main(String[] args) {
        String duty = getDutyTime("2020-08-06 19:30:00");
        System.out.println(duty);
    }
}
